/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* vim: set ts=8 sts=2 et sw=2 tw=80: *//* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. *//* * Base class for DOM Core's nsIDOMComment, nsIDOMDocumentType, nsIDOMText, * nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes. */#ifndef nsGenericDOMDataNode_h___#define nsGenericDOMDataNode_h___#include"mozilla/Attributes.h"#include"nsIContent.h"#include"nsTextFragment.h"#include"nsError.h"#include"mozilla/dom/Element.h"#include"nsCycleCollectionParticipant.h"#include"nsISMILAttr.h"#include"mozilla/dom/ShadowRoot.h"classnsIDocument;classnsIDOMText;#define DATA_NODE_FLAG_BIT(n_) NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_))// Data node specific flagsenum{// This bit is set to indicate that if the text node changes to// non-whitespace, we may need to create a frame for it. This bit must// not be set on nodes that already have a frame.NS_CREATE_FRAME_IF_NON_WHITESPACE=DATA_NODE_FLAG_BIT(0),// This bit is set to indicate that if the text node changes to// whitespace, we may need to reframe it (or its ancestors).NS_REFRAME_IF_WHITESPACE=DATA_NODE_FLAG_BIT(1),// This bit is set to indicate that we have a cached// TextIsOnlyWhitespace valueNS_CACHED_TEXT_IS_ONLY_WHITESPACE=DATA_NODE_FLAG_BIT(2),// This bit is only meaningful if the NS_CACHED_TEXT_IS_ONLY_WHITESPACE// bit is set, and if so it indicates whether we're only whitespace or// not.NS_TEXT_IS_ONLY_WHITESPACE=DATA_NODE_FLAG_BIT(3),};// Make sure we have enough space for those bitsASSERT_NODE_FLAGS_SPACE(NODE_TYPE_SPECIFIC_BITS_OFFSET+4);#undef DATA_NODE_FLAG_BITclassnsGenericDOMDataNode:publicnsIContent{public:NS_DECL_CYCLE_COLLECTING_ISUPPORTSNS_DECL_SIZEOF_EXCLUDING_THISexplicitnsGenericDOMDataNode(already_AddRefed<mozilla::dom::NodeInfo>&aNodeInfo);explicitnsGenericDOMDataNode(already_AddRefed<mozilla::dom::NodeInfo>&&aNodeInfo);virtualvoidGetNodeValueInternal(nsAString&aNodeValue)override;virtualvoidSetNodeValueInternal(constnsAString&aNodeValue,mozilla::ErrorResult&aError)override;// Implementation for nsIDOMCharacterDatansresultGetData(nsAString&aData)const;nsresultSetData(constnsAString&aData);nsresultGetLength(uint32_t*aLength);nsresultSubstringData(uint32_taOffset,uint32_taCount,nsAString&aReturn);nsresultAppendData(constnsAString&aArg);nsresultInsertData(uint32_taOffset,constnsAString&aArg);nsresultDeleteData(uint32_taOffset,uint32_taCount);nsresultReplaceData(uint32_taOffset,uint32_taCount,constnsAString&aArg);// nsINode methodsvirtualuint32_tGetChildCount()constoverride;virtualnsIContent*GetChildAt(uint32_taIndex)constoverride;virtualnsIContent*const*GetChildArray(uint32_t*aChildCount)constoverride;virtualint32_tIndexOf(constnsINode*aPossibleChild)constoverride;virtualnsresultInsertChildAt(nsIContent*aKid,uint32_taIndex,boolaNotify)override;virtualvoidRemoveChildAt(uint32_taIndex,boolaNotify)override;virtualvoidGetTextContentInternal(nsAString&aTextContent,mozilla::OOMReporter&aError)override{GetNodeValue(aTextContent);}virtualvoidSetTextContentInternal(constnsAString&aTextContent,mozilla::ErrorResult&aError)override{// Batch possible DOMSubtreeModified events.mozAutoSubtreeModifiedsubtree(OwnerDoc(),nullptr);returnSetNodeValue(aTextContent,aError);}// Implementation for nsIContentvirtualnsresultBindToTree(nsIDocument*aDocument,nsIContent*aParent,nsIContent*aBindingParent,boolaCompileEventHandlers)override;virtualvoidUnbindFromTree(boolaDeep=true,boolaNullParent=true)override;virtualalready_AddRefed<nsINodeList>GetChildren(uint32_taFilter)override;nsresultSetAttr(int32_taNameSpaceID,nsIAtom*aName,constnsAString&aValue,boolaNotify){returnSetAttr(aNameSpaceID,aName,nullptr,aValue,aNotify);}virtualnsresultSetAttr(int32_taNameSpaceID,nsIAtom*aAttribute,nsIAtom*aPrefix,constnsAString&aValue,boolaNotify)override;virtualnsresultUnsetAttr(int32_taNameSpaceID,nsIAtom*aAttribute,boolaNotify)override;virtualconstnsAttrName*GetAttrNameAt(uint32_taIndex)constoverride;virtualmozilla::dom::BorrowedAttrInfoGetAttrInfoAt(uint32_taIndex)constoverride;virtualuint32_tGetAttrCount()constoverride;virtualconstnsTextFragment*GetText()override;virtualuint32_tTextLength()constoverride;virtualnsresultSetText(constchar16_t*aBuffer,uint32_taLength,boolaNotify)override;// Need to implement this here too to avoid hiding.nsresultSetText(constnsAString&aStr,boolaNotify){returnSetText(aStr.BeginReading(),aStr.Length(),aNotify);}virtualnsresultAppendText(constchar16_t*aBuffer,uint32_taLength,boolaNotify)override;virtualboolTextIsOnlyWhitespace()override;virtualboolThreadSafeTextIsOnlyWhitespace()constfinal;virtualboolHasTextForTranslation()override;virtualvoidAppendTextTo(nsAString&aResult)override;MOZ_MUST_USEvirtualboolAppendTextTo(nsAString&aResult,constmozilla::fallible_t&)override;virtualvoidSaveSubtreeState()override;#ifdef DEBUGvirtualvoidList(FILE*out,int32_taIndent)constoverride;virtualvoidDumpContent(FILE*out,int32_taIndent,boolaDumpAll)constoverride;#endifvirtualnsIContent*GetBindingParent()constoverride;virtualnsXBLBinding*GetXBLBinding()constoverride;virtualvoidSetXBLBinding(nsXBLBinding*aBinding,nsBindingManager*aOldBindingManager=nullptr)override;virtualmozilla::dom::ShadowRoot*GetContainingShadow()constoverride;virtualnsTArray<nsIContent*>&DestInsertionPoints()override;virtualnsTArray<nsIContent*>*GetExistingDestInsertionPoints()constoverride;virtualvoidSetShadowRoot(mozilla::dom::ShadowRoot*aShadowRoot)override;virtualnsIContent*GetXBLInsertionParent()constoverride;virtualvoidSetXBLInsertionParent(nsIContent*aContent)override;virtualboolIsNodeOfType(uint32_taFlags)constoverride;virtualboolIsLink(nsIURI**aURI)constoverride;NS_IMETHODWalkContentStyleRules(nsRuleWalker*aRuleWalker)override;NS_IMETHOD_(bool)IsAttributeMapped(constnsIAtom*aAttribute)const;virtualnsChangeHintGetAttributeChangeHint(constnsIAtom*aAttribute,int32_taModType)const;virtualnsresultClone(mozilla::dom::NodeInfo*aNodeInfo,nsINode**aResult,boolaPreallocateChildren)constoverride{nsCOMPtr<nsINode>result=CloneDataNode(aNodeInfo,true);result.forget(aResult);if(!*aResult){returnNS_ERROR_OUT_OF_MEMORY;}returnNS_OK;}nsresultSplitData(uint32_taOffset,nsIContent**aReturn,boolaCloneAfterOriginal=true);// WebIDL API// Our XPCOM GetData is just fine for WebIDLvirtualvoidSetData(constnsAString&aData,mozilla::ErrorResult&rv){rv=SetData(aData);}// nsINode::Length() returns the right thing for our length attributevoidSubstringData(uint32_taStart,uint32_taCount,nsAString&aReturn,mozilla::ErrorResult&rv);voidAppendData(constnsAString&aData,mozilla::ErrorResult&rv){rv=AppendData(aData);}voidInsertData(uint32_taOffset,constnsAString&aData,mozilla::ErrorResult&rv){rv=InsertData(aOffset,aData);}voidDeleteData(uint32_taOffset,uint32_taCount,mozilla::ErrorResult&rv){rv=DeleteData(aOffset,aCount);}voidReplaceData(uint32_taOffset,uint32_taCount,constnsAString&aData,mozilla::ErrorResult&rv){rv=ReplaceData(aOffset,aCount,aData);}//----------------------------------------#ifdef DEBUGvoidToCString(nsAString&aBuf,int32_taOffset,int32_taLen)const;#endifNS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsGenericDOMDataNode)protected:virtual~nsGenericDOMDataNode();virtualmozilla::dom::Element*GetNameSpaceElement()override{nsINode*parent=GetParentNode();returnparent&&parent->IsElement()?parent->AsElement():nullptr;}/** * There are a set of DOM- and scripting-specific instance variables * that may only be instantiated when a content object is accessed * through the DOM. Rather than burn actual slots in the content * objects for each of these instance variables, we put them off * in a side structure that's only allocated when the content is * accessed through the DOM. */classnsDataSlots:publicnsINode::nsSlots{public:nsDataSlots();voidTraverse(nsCycleCollectionTraversalCallback&cb);voidUnlink();/** * The nearest enclosing content node with a binding that created us. * @see nsIContent::GetBindingParent */nsIContent*mBindingParent;// [Weak]/** * @see nsIContent::GetXBLInsertionParent */nsCOMPtr<nsIContent>mXBLInsertionParent;/** * @see nsIContent::GetContainingShadow */RefPtr<mozilla::dom::ShadowRoot>mContainingShadow;/** * @see nsIContent::GetDestInsertionPoints */nsTArray<nsIContent*>mDestInsertionPoints;};// Override from nsINodevirtualnsINode::nsSlots*CreateSlots()override;nsDataSlots*DataSlots(){returnstatic_cast<nsDataSlots*>(Slots());}nsDataSlots*GetExistingDataSlots()const{returnstatic_cast<nsDataSlots*>(GetExistingSlots());}nsresultSplitText(uint32_taOffset,nsIDOMText**aReturn);nsresultGetWholeText(nsAString&aWholeText);staticint32_tFirstLogicallyAdjacentTextNode(nsIContent*aParent,int32_taIndex);staticint32_tLastLogicallyAdjacentTextNode(nsIContent*aParent,int32_taIndex,uint32_taCount);nsresultSetTextInternal(uint32_taOffset,uint32_taCount,constchar16_t*aBuffer,uint32_taLength,boolaNotify,CharacterDataChangeInfo::Details*aDetails=nullptr);/** * Method to clone this node. This needs to be overriden by all derived * classes. If aCloneText is true the text content will be cloned too. * * @param aOwnerDocument the ownerDocument of the clone * @param aCloneText if true the text content will be cloned too * @return the clone */virtualnsGenericDOMDataNode*CloneDataNode(mozilla::dom::NodeInfo*aNodeInfo,boolaCloneText)const=0;nsTextFragmentmText;public:virtualboolOwnedOnlyByTheDOMTree()override{returnGetParent()&&mRefCnt.get()==1;}virtualboolIsPurple()override{returnmRefCnt.IsPurple();}virtualvoidRemovePurple()override{mRefCnt.RemovePurple();}private:already_AddRefed<nsIAtom>GetCurrentValueAtom();};#endif /* nsGenericDOMDataNode_h___ */